home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
scope
/
101-125
/
scopedisk116
/
magman
/
magman.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-19
|
10KB
|
410 lines
/* MAGMAN.C - Magazine Articles Manager for the Commodore Amiga computer.
Copyright 1990 by Mike Budahn
Searches a comma-delimited, ASCII file for string matches.
The file must contain the magazine title in the first field,
the issue date in the next field, and comma/space-delimited
fields of topic keywords. A carriage return ends the record.
COMPILE: lc -v -Lcd
NOTE: Optimizing adds 12 bytes.
VERS-DATE--NOTES
---------------
2.02-03/90-Fixed a terrible bug which caused some of the data file
buffers to be over-written by junk. The problem was that the keyword
gadget allowed for more input than the buffer provided. As a result,
after the filling up the buffer, the gadget kept taking input, stuffing
it into whatever memory it was around. Gotta watch that.
2.01-02/90-Removed the console window which showed up when running from
WorkBench. Added a Find menu selection. Moved the window to upper left
corner.
2.00-01/90-Fully Amigatized with both enter & search functions combined
into this one module. Menu added.
1.05-12/89-Eliminated lots of variables by printing one item at a time;
shortened window. Added prompts to the window title. Added mycopy(),
fixed bug which prevented the program from finding items in the
database which were followed by COMMAs or EOLs.
1.00-08/89-Original version.
*/
#include <exec/types.h>
#include <intuition/intuition.h>
#include <proto/intuition.h>
#include <proto/exec.h>
#include <stdio.h>
#include "magman.h"
#define FILENAME "MAG:DataBase"
#define m_Rp window->RPort
/* Setup Defaults */
#define MAX_STRING 256
/* Gadget Numbers */
#define WORDSGADGET 3
#define ISSUEGADGET 2
#define TITLEGADGET 1
#define FINDGADGET 0
/* Menus */
#define ADDDATA 0
#define SAVEDATA 1
#define FINDDATA 2
/* Character Codes */
#define EOL 10 /* End of file line character is hex 0A */
#define COMMA 44 /* ASCII comma is decimal 44 */
#define ESCKEY 27 /* The Escape Key */
#define SPACE ' ' /* White Space */
char *msg_Intro = "Magazine Manager V.2.02 by Mike Budahn" ;
char *msg_Header = "MagMan» Enter Data." ;
char *msg_SavedOK = "MagMan» Data Saved Okay." ;
char *msg_Searching = "MagMan» Searching...Wait..." ;
char *msg_EndSearch = "MagMan» Search Completed." ;
char *msg_DoSearch = "MagMan» Enter Text To Search For." ;
char *msg_FileError = "STATUS» Data Not Saved. Error Opening File." ;
char *msg_FieldError = "STATUS» Data Not Saved. A Field Is Empty." ;
char *msg_IOError = "STATUS» Error Opening Database." ;
char *msg_Prompt = "...ESC TO QUIT...ANY KEY TO CONTINUE..." ;
struct IntuitionBase *IntuitionBase ;
struct GfxBase *GfxBase ;
struct Window *window ;
struct IntuiMessage *message ;
struct IntuitionBase *OpenLibrary() ;
struct GfxBase *OpenLibrary() ;
struct Window *OpenWindow() ;
void open_all(void) ;
void close_all(int) ;
void clear_gadgets(void) ;
void init(UBYTE *) ;
void find_match(void) ;
int handle_gadget(struct Gadget *) ;
int handle_menu(long) ;
int pause(void) ;
int str_position(char *, char *) ;
char *mycopy(char *, char *) ;
void _main()
{
APTR address ;
ULONG class ;
USHORT code ;
USHORT again = TRUE ;
/*
Open everything but the database file.
*/
open_all() ;
/*
Loop until the close window gadget is clicked.
Note: right now, errors do not abort the loop.
Close the window yourself after irresolvable STATUS messages.
*/
do {
Wait(1<<window->UserPort->mp_SigBit) ;
while ((message = (struct IntuiMessage *)GetMsg(window->UserPort)) != NULL)
{
class = message->Class ;
code = message->Code ;
address = message->IAddress ;
ReplyMsg((struct Message *)message) ;
switch (class) {
/**/
case CLOSEWINDOW:
again = FALSE ;
break ;
/**/
case GADGETUP:
again = handle_gadget((struct Gadget *)address) ;
break ;
/**/
case MENUPICK:
again = handle_menu(code) ;
break ;
}
}
} while (again == TRUE) ;
close_all(0) ;
}
int handle_menu(long m_number)
{
FILE *out_file, *fopen() ;
struct MenuItem *menu ;
long item ;
/*
Find the last menu item selected,
although use of command keys is obviously most convenient.
*/
while (m_number != MENUNULL) {
item = m_number ;
menu = (struct MenuItem *)ItemAddress(&Menu1, m_number) ;
m_number = menu->NextSelect ;
}
/*
Just in case of an errant item number.
*/
if (item == MENUNULL) return(TRUE) ;
switch (ITEMNUM(item)) {
/**/
case SAVEDATA:
/* Make sure every buffer contains something. */
if (strlen(TitleSIBuff)<1 || strlen(IssueSIBuff)<1 || strlen(KeywordsSIBuff)<1) {
SetWindowTitles(window, msg_FieldError, NULL) ;
break ;
}
/* Open the file. */
if (!(out_file = fopen(FILENAME, "a"))) {
SetWindowTitles(window, msg_FileError, NULL) ;
break ;
}
/* Write the data. */
fprintf(out_file, "%s, %s, %s\n", TitleSIBuff, IssueSIBuff, KeywordsSIBuff) ;
fclose(out_file) ;
SetWindowTitles(window, msg_SavedOK, NULL) ;
break ;
/**/
case ADDDATA:
clear_gadgets() ;
SetWindowTitles(window, msg_Header, NULL) ;
ActivateGadget(&Title, window, NULL) ;
break ;
/**/
case FINDDATA:
clear_gadgets() ;
SetWindowTitles(window, msg_DoSearch, NULL) ;
ActivateGadget(&Find, window, NULL) ;
break ;
/**/
default:
break ;
}
return(TRUE) ;
}
int handle_gadget(struct Gadget *gadget)
{
switch(gadget->GadgetID) {
/**/
case TITLEGADGET:
ActivateGadget(&Issue, window, NULL) ;
break ;
/**/
case ISSUEGADGET:
ActivateGadget(&Keywords, window, NULL) ;
break ;
/**/
case WORDSGADGET:
break ;
/**/
case FINDGADGET:
/*
If the Find Gadget is tripped by the Enter key, we automatically
assume a search is wanted. Double-check the buffer for data.
*/
if (FindSIBuff[0] == NULL) break ;
find_match() ;
init(&FindSIBuff[0]) ;
/*
Only refresh one gadget -- this one.
*/
RefreshGList(&Find, window, NULL, 1) ;
break ;
/**/
default:
break ;
}
return(TRUE) ;
}
void clear_gadgets()
{
init(&KeywordsSIBuff[0]) ;
init(&IssueSIBuff[0]) ;
init(&TitleSIBuff[0]) ;
RefreshGadgets(&Title, window, NULL) ;
}
void init(UBYTE *string)
{
while (*string != '\0') {
*string = '\0' ;
*string++ ;
}
return ;
}
/*
BEGINNING OF CODE TO SEARCH DATABASE */
/* ************************************** */
void find_match()
{
FILE *input_file, *fopen() ;
int success, str_position(), pause() ;
char *p, *mycopy(), string[MAX_STRING] ;
/*
Find the database file.
*/
if ((input_file = fopen(FILENAME, "r")) == NULL)
{
SetWindowTitles(window, msg_IOError, NULL) ;
return ;
}
/*
Set up the window.
*/
clear_gadgets() ;
SetWindowTitles(window, msg_Searching, NULL) ;
/*
Get a line from the database.
*/
while (fgets(string, MAX_STRING, input_file))
{
/* copy the title */
p = mycopy(TitleSIBuff, string) ;
/* copy the issue */
p = mycopy(IssueSIBuff, p) ;
/* until the EOL is reached, copy each item into the buffer */
do {
p = mycopy(KeywordsSIBuff, p) ;
/*
Success will equal -1 if the keyword is not found.
*/
if ((success = str_position(KeywordsSIBuff, FindSIBuff)) != -1) {
RefreshGadgets(&Title, window, NULL) ;
SetWindowTitles(window, msg_Prompt, NULL) ;
success = pause() ;
switch (success) {
/*
Close window gadget clicked.
*/
case -2:
fclose(input_file) ;
close_all(0) ;
/*
Either ESC was pressed or file exhausted.
*/
case -1:
fclose(input_file) ;
SetWindowTitles(window, msg_EndSearch, NULL) ;
return ;
/*
Continue searching.
*/
default:
init(&KeywordsSIBuff[0]) ;
break ;
}
SetWindowTitles(window, msg_Searching, NULL) ;
}
} while (p != NULL) ;
clear_gadgets() ;
}
fclose(input_file) ;
SetWindowTitles(window, msg_EndSearch, NULL) ;
return ;
}
/*
mycopy(to, from) - copy src string to dest.
Return the address of source.
*/
char *mycopy(dest, src)
register char *dest, *src ;
{
/*
Skip the white space and trap for missing data.
*/
while ((*src == SPACE) && (*src != EOL)) *src++ ;
/*
Copy to the comma or end of line.
*/
while ((*src != COMMA) && (*src != EOL)) *dest++ = *src++ ;
/*
Tack on NULL for good measure.
*/
*dest = '\0' ;
/*
If the source string is at a comma, move past it,
and return the up-dated string position.
*/
if (*src == COMMA) {
*src++ ;
return (src) ;
}
/*
Otherwise we're at the end of the line.
*/
return (NULL) ;
}
/*
str_position (s1, s2) - case insensitive search of s1 for s2.
Return an integer indicating the number of characters preceeding
the string found, or -1 if the string is not found.
*/
int str_position(friskme, findme)
char friskme[] ; /* string to search */
char findme[] ; /* string to search for */
{
int pos, match ;
for (pos=0, match=0; pos<=strlen(friskme)-strlen(findme); pos++)
{
match = strnicmp(&friskme[pos], &findme[0], strlen(findme)) ;
if (match == 0) return(pos) ;
}
return(-1) ;
}
/*
pause() - wait for VANILLAKEY press.
Return 0 if aok, continue search.
Return -1 if abort search.
Return -2 to close window.
*/
int pause()
{
ULONG class ;
USHORT code ;
Wait(1 << window->UserPort->mp_SigBit) ;
while ((message = (struct IntuiMessage *)GetMsg(window->UserPort)) != NULL) {
class = message->Class ;
code = message->Code ;
ReplyMsg((struct Message *)message) ;
}
switch (class) {
case CLOSEWINDOW:
return(-2) ;
/**/
case VANILLAKEY:
if (code == ESCKEY) return(-1) ;
return(0) ;
/**/
default:
return(-1) ;
}
}
/*
END OF CODE FOR SEARCHING DATABASE */
/* ************************************ */
void open_all()
{
if (!(IntuitionBase = OpenLibrary("intuition.library",0))) {
close_all(10) ;
}
if (!(GfxBase = OpenLibrary("graphics.library", 0))) {
close_all(20) ;
}
if (!(window = OpenWindow(&NewWindowStructure1))) {
close_all(30) ;
}
SetMenuStrip(window, &Menu1) ;
SetWindowTitles(window, msg_Intro, NULL) ;
return ;
}
void close_all(int status)
{
if (window) ClearMenuStrip(window) ;
if (window) CloseWindow(window) ;
if (GfxBase) CloseLibrary(GfxBase) ;
if (IntuitionBase) CloseLibrary(IntuitionBase) ;
_exit(status) ;
}